package com.naiterui.common.repository.hibernate;

import java.util.List;
import java.util.Map;

import org.hibernate.query.Query;
import org.hibernate.type.Type;

import com.naiterui.common.repository.page.Page;

/**
 * 基于SQL语句的持久层封装
 * 主要用于定义基于SQL的操作方法
 * @author zhouyanxin
 * @since 1.0.0
 */
public interface INativeQLDao {

    /**
     * 通过sql 查询记录总数
     *
     * @param sql
     * @param values
     *
     * @return
     */
    Long getSqlCount(String sql, Object... values);

    /**
     * 通过sql 查询记录总数,支持使用list where fund_id=:fundId and freeze_type in (:freezeType)
     *
     * @param sql
     * @param values
     *
     * @return
     */
    Long getSqlCount(String sql, Map<String, ?> paramMap);

    /**
     * 获取执行指定SQL的Query(NativeQuery)对象
     * INativeQLDao.getSQLQuery()
     * @author zhouyanxin
     * @date 2018年5月11日
     * @since 1.0.0
     * @param sql 需要查询的SQL语句
     * @param values SQL语句中需要注入的参数
     * @return Query对象
     */
    Query<?> getSQLQuery(String sql, Object... values);

    /**
     * SQL查询
     * 将查询结果映射为执行类型的对象
     * 当前采用JdbcTemplate进行实现
     * 指定结果集对象映射的类型可实现ORM
     * INativeQLDao.sqlQuery()
     * @author zhouyanxin
     * @date 2018年5月9日
     * @since 1.0.0
     * @param requiredType 查询结果需要映射的类型
     * @param sql 需要查询的SQL语句
     * @param values SQL语句中需要注入的参数
     * @return 查询结果映射的对应结果集
     */
    <E> List<E> sqlQuery(Class<E> requiredType, String sql, Object... values);

    /**
     * 用于更新类(insert、update、delete)操作
     * 并返回受影响的记录数
     * INativeQLDao.executeSQLResult()
     * @author zhouyanxin
     * @date 2018年5月11日
     * @since 1.0.0
     * @param sql 需要执行的SQL语句
     * @param values SQL语句中需要注入的参数
     * @return SQL执行影响的记录数
     */
    int executeSQLResult(String sql, Object... values);

    /**
     * 用于更新类(insert、update、delete)操作 update table set name = 'test'，where fund_id=:fundId and freeze_type in (:freezeType)
     *
     * @param sql      需要执行的SQL语句
     * @param paramMap SQL注入参数，支持LIST
     *
     * @return SQL执行影响的记录数
     */
    int executeSQLResult(String sql, Map<String, ?> paramMap);

    /**
     * 标准SQL查询
     * INativeQLDao.findBySQLQuery()
     * @author zhouyanxin
     * @date 2018年5月11日
     * @since 1.0.0
     * @param sql 需要查询的SQL语句
     * @param values SQL语句中需要注入的参数
     * @return 返回原生结果
     */
    <E> List<E> findBySQLQuery(String sql, Object... values);

    /**
     * 用于更新类(insert、update、delete)操作
     * INativeQLDao.executeSQL()
     * @author zhouyanxin
     * @date 2018年5月11日
     * @since 1.0.0
     * @param sql 需要执行的SQL语句
     * @param values SQL语句中需要注入的参数
     */
    void executeSQL(String sql, Object... values);

    /**
     * 批量操作
     * 受限于目前采用主键自增方式等因素
     * 该方法目前并不具备批量的性能优化
     * INativeQLDao.batch()
     * @author zhouyanxin
     * @date 2018年5月11日
     * @since 1.0.0
     * @param sql 需要执行的SQL语句
     * @param parameters 批量参数注入，每一个Object数组为一条需要操作的记录
     */
    void batch(String sql, List<Object[]> parameters);

    /**
     * 基于SQL的分页查询
     * 内部采用JdbcTemplate进行实现
     * 通过执行结果集映射的对象类型可实现ORM
     * INativeQLDao.pagedSqlQuery()
     * @author zhouyanxin
     * @date 2018年5月11日
     * @since 1.0.0
     * @param clazz
     * @param sql 查询SQL语句
     * @param pageNo 当前页
     * @param pageSize 每页显示记录数
     * @param values 查询条件参数注入
     * @return
     */
    <E> Page<E> pagedSqlQuery(Class<E> clazz, String sql, int pageNo, int pageSize, Object... values);

    /**
     * 基于SQL的分页查询
     * 内部采用JdbcTemplate进行实现
     * 通过执行结果集映射的对象类型可实现ORM
     * 增加offset参数用于实现流式分页
     * INativeQLDao.pagedSqlQueryOffset()
     * @author zhouyanxin
     * @date 2018年5月11日
     * @since 1.0.0
     * @param clazz
     * @param sql 查询SQL语句
     * @param pageNo 当前页
     * @param pageSize 每页显示记录数
     * @param offset
     * @param values 查询条件参数注入
     * @return
     */
    <E> Page<E> pagedSqlQueryOffset(Class<E> clazz, String sql, int pageNo, int pageSize, int offset, Object... values);

    /**
     * 将满足SQL条件的结果集映射映射成clazz类型的集合，通过scalarMap指定转换类型
     * 该方法废弃，可以使用pagedSqlQuery(Class<E> clazz, String sql, int pageNo, int pageSize, Object...
     * values)进行替代
     * INativeQLDao.pagedSqlQueryAliasToBean()
     * @author zhouyanxin
     * @date 2018年5月11日
     * @since 1.0.0
     * @param clazz
     * @param scalarMap
     * @param sql 查询SQL语句
     * @param pageNo 当前页
     * @param pageSize 每页显示记录数
     * @param values 查询条件参数注入
     * @return
     */
    @Deprecated
    <E> Page<E> pagedSqlQueryAliasToBean(Class<E> clazz, Map<String, Type> scalarMap, String sql, int pageNo, int pageSize, Object... values);

    /**
     * 将满足SQL条件的结果集映射映射成clazz类型的集合
     * 该方法废弃，可以使用sqlQuery(Class<E> clazz, String sql, Object... values);进行替代
     * INativeQLDao.sqlQuery2Bean()
     * @author zhouyanxin
     * @date 2018年5月9日
     * @since 1.0.0
     * @param clazz
     * @param sql 查询SQL语句
     * @param values 查询条件参数注入
     * @return
     * @deprecated use {@link #sqlQuery(Class, String, Object[])}
     */
    @Deprecated
    <E> List<E> sqlQuery2Bean(Class<E> clazz, String sql, Object... values);

    /**
     * 执行sql，一般用于insert/update/delete等操作
     * 废弃该方法，使用executeSQL(String sql, Object... values);进行代替
     * INativeQLDao.executeSQL()
     * @author zhouyanxin
     * @date 2018年5月11日
     * @since 1.0.0
     * @param sql 需要执行的SQL语句
     * @deprecated use {@link #executeSQL(String, Object[])}
     */
    @Deprecated
    void executeSQL(String sql);
}
